#include "i2c.h"
#include "delay.h"

// ?????? I2C_Soft_Init
void I2C_Soft_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_PORT, &GPIO_InitStructure);
    
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN | I2C_SDA_PIN);
}

// ??I2C??????

void I2C_Start(void) {
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(5);
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
}

void I2C_Stop(void) {
    GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN);
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(5);
}

void I2C_SendByte(uint8_t data) {
    uint8_t i;
    
    for(i=0; i<8; i++) {
        GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
        if(data & 0x80) {
            GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
        } else {
            GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN);
        }
        data <<= 1;
        delay_us(2);
        GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
        delay_us(5);
        GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
        delay_us(2);
    }
    
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(2);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
}

uint8_t I2C_ReceiveByte(void) {
    uint8_t i, data = 0;
    
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    
    for(i=0; i<8; i++) {
        GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
        delay_us(2);
        GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
        data <<= 1;
        if(GPIO_ReadInputDataBit(I2C_PORT, I2C_SDA_PIN)) {
            data |= 0x01;
        }
        delay_us(5);
    }
    
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
    return data;
}

uint8_t I2C_WaitAck(void) {
    uint8_t ack = 0;
    
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(2);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    
    if(GPIO_ReadInputDataBit(I2C_PORT, I2C_SDA_PIN)) {
        ack = 1;
    }
    
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
    return ack;
}

void I2C_Ack(void) {
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
    GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(2);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
}

void I2C_NAck(void) {
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
    GPIO_SetBits(I2C_PORT, I2C_SDA_PIN);
    delay_us(2);
    GPIO_SetBits(I2C_PORT, I2C_SCL_PIN);
    delay_us(5);
    GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN);
}